package com.luke.nio.group_chat;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;

/**
 * @Descrtption GroupChatClient
 * @Author luke
 * @Date 2020/4/27
 **/
public class GroupChatClient {

    private static  final int PORT = 8765;

    private SocketChannel socketChannel;

    public static void main(String[] args) throws IOException{
        new GroupChatClient();
    }

    public GroupChatClient() throws IOException {

        //创建SocketChannel
        socketChannel = SocketChannel.open();
        socketChannel.configureBlocking(false);
        //创建Selector实例
        Selector selector = Selector.open();

        //连接服务端
        InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", PORT);
        if (!socketChannel.connect(inetSocketAddress)) {
            while (!socketChannel.finishConnect()) {
                System.out.println("没有阻塞，可以执行其他工作");
            }
            System.out.println("连接服务端成功，本地地址"+socketChannel.getLocalAddress());
        }

        //注册到选择器上
        socketChannel.register(selector, SelectionKey.OP_READ);

        //子线程通过Selector轮询检查有事件发生的通道
        new Thread(() -> {
            try {
                recvDataFromServer(selector);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();

        //主线程从控制台接收消息，发送到服务端
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextLine()){
            String message = scanner.nextLine();
            sendDataToServer(message);
        }

    }

    //接收服务端消息
    private void recvDataFromServer(Selector selector) throws IOException{
        while (true){
            int selectCount = selector.select(2000); //轮询操作
            if(selectCount > 0){
                //获取所有事件发生的SelectionKey
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                Iterator<SelectionKey> selectionKeyIterator = selectionKeys.iterator();
                while (selectionKeyIterator.hasNext()){
                    SelectionKey selectionKey = selectionKeyIterator.next();
                    System.out.println("有事件发生");
                    if(selectionKey.isReadable()){//OP_READ事件，接收到服务端消息
                        SocketChannel channel = (SocketChannel)selectionKey.channel();
                        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                        channel.read(byteBuffer);
                        System.out.println("客户端接收到消息："+new String(byteBuffer.array()));
                    }
                    selectionKeyIterator.remove();
                }
            }else{
                //没有事件发生，可以执行其他操作
            }
        }

    }

    //发送消息给服务端
    private void sendDataToServer(String message) throws IOException{
        //将消息发送到服务器端
        String info = "【"+socketChannel.getLocalAddress()+"】发送消息:" + message;
        socketChannel.write(ByteBuffer.wrap(info.getBytes()));
        System.out.println(info);
    }

}
